#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <linux/rtc.h>
/* for net */
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>    
#include <net/if.h>
/* for signal & time */
#include <signal.h>    
#include <time.h>
#include <sys/time.h>
#include <fcntl.h>    
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <termios.h>
/* share memory */
#include <sys/ipc.h>
/*  pthread  */
#include <pthread.h>
/* user head file */
#include "os_struct.h"
#include "mainBoard.h" 
#include "queue.h"

#define  NOT_ACTIVE      0xEE     //设备不在线状态EE(代表Error)
#define  TX_BUFFER_SIZE   500 
#define  DEFAULT_PORT    60001    //默认端口
#define  BUFF_SIZE       512    //buffer大小
#define  SELECT_TIMEOUT  1       //select的timeout seconds 

OS_UART   uart0;
CMD_LIST  task;
OS_BOARD  s3c44b0x;
OS_SERVER master;
TASKQUEUE fifo_alarm;

int alarmfd = 0, uart0fd = 0, rtcfd = 0,uart1fd = 0;

unsigned char poll_sim3u146_cmd[7] = {0x7e,0x00,0x05,0x20,0x00,0x00,0x5a};
unsigned char crcRight[9] = {0x7e,0x00,0x07,0xA6,0x00,0x01,0x00,0x00,0x5a};
unsigned char crcWrong[9] = {0x7e,0x00,0x07,0xF6,0x00,0x00,0x00,0x00,0x5a}; 

unsigned char Maxframenum = 0;
unsigned char mobile_temp_data[300] = {'\0'};
unsigned char cs8900_temp_data[300] = {'\0'}; 
unsigned char transm_temp_data[300] = {'\0'}; 

static unsigned char reply_buf[9] = {'\0'};
static unsigned char TransmitRight[9] = {0x7e,0x00,0x07,0xA6,0x00,0x01,0x00,0x00,0x5a};
static unsigned char TransmitWrong[9] = {0x7e,0x00,0x07,0xF6,0x00,0x00,0x00,0x00,0x5a}; 
volatile unsigned char deviceUpdate = 0x0;
extern unsigned char update_frames[12];
extern unsigned char update_status[12];

pthread_mutex_t mobile_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_mutex_t alarm_mutex = PTHREAD_MUTEX_INITIALIZER; 

extern void *gap_recv_thid(void *arg);

/*
 * This function is used to debug board info ...
 */
static void error_exit(unsigned char  error_num)
{
	unsigned char data[6];

	memset(data,0,6);
	memset(data,error_num,6);
	write(uart0fd,data,6);
	exit(1);
}

static void open_devices(void)
{
	/* open 告警灯 */
	alarmfd = open("/dev/alarm",O_RDWR);
	if(alarmfd < 0){
		error_exit(4);
	}
	/* open 计时器 */
	rtcfd = open("/dev/rtc0",O_RDWR);
	if(rtcfd < 0){
		error_exit(5);
	}	

	/* open uart0 & uart1 ,set nonblock*/
	serial_init();
}

/*
 *	For use to read MAC (6Bytes)
 *	Failed return 0
 *	success return 1
 */
static int read_mac(void)
{
	FILE *fp = NULL;
	int flen = 0;
	unsigned char buf[10];	
	int i ;

	fp = fopen("/var/yaffs/mac.bin","rb");
	if(fp == NULL){
		return 0;
	}else{
		fseek(fp,0,SEEK_END);
		flen = ftell(fp);
		if(flen == 0){
			fclose(fp);
			fp = NULL;
			return 0; // not config .
		}
	}

	fseek(fp,0,SEEK_SET);
	memset(buf,0,sizeof(buf));
	fread(buf,sizeof(unsigned char),6,fp);
	
	memset(&s3c44b0x.mac[0],0,6);
	memcpy(&s3c44b0x.mac[0],buf,6);

	fclose(fp);
	fp = NULL;

	return 1;
}


/*
 * For use to read UUID (16Bytes)
 * return value: 
 * 			0 : Failed 		| not Configed yet 
 * 			1 : success		| Configed!
 */
static int read_uuid(unsigned char *userinfo)
{
	FILE *fp = NULL;
	int flen = 0;
	unsigned char buf[20];	
	int i ;

	fp = fopen("/var/yaffs/uuid.bin","rb");
	if(fp == NULL){
		return 0;
	}else{
		fseek(fp,0,SEEK_END);
		flen = ftell(fp);
		if(flen == 0){
			fclose(fp);
			fp = NULL;
			return 0; // not config .
		}
	}

	fseek(fp,0,SEEK_SET);
	memset(buf,0,sizeof(buf));
	fread(buf,sizeof(unsigned char),16,fp);
	
	memcpy(userinfo,buf,16);
	
	fclose(fp);
	fp = NULL;

	return 1;
}
/*
 * read board's: ip+gateway+netmask+seraddr+port+deviceName 
 * return value: 
 * 			0 : Failed 		| not Configed yet 
 * 			1 : success		| Configed!
 */
static int read_bd_info(unsigned char *userinfo)
{
	FILE *fp = NULL;
	int flen = 0;
	unsigned char buf[110];	
	int i ;

	fp = fopen("/var/yaffs/boardinfo.bin","rb");
	if(fp == NULL){
		return 0;;
	}else{
		fseek(fp,0,SEEK_END);
		flen = ftell(fp);
		if(flen == 0){
			fclose(fp);
			fp = NULL;
			return 0; // not config .
		}
	}

	fseek(fp,1,SEEK_SET);
	memset(buf,0,sizeof(buf));
	fread(buf,sizeof(unsigned char),103,fp);
	
	memcpy(userinfo,buf,103);

	fclose(fp);
	fp = NULL;

	return 1;
}
/*
 * read board's info : uuid + read_bd_info 
 * 
 */
static int read_dev_info(OS_BOARD *dev)
{
	unsigned char readbuf[130];

	memset(readbuf,0,sizeof(readbuf));

	if(read_mac() == 0){
		/* if mac == NULL,use default MAC addr in kernel */
		printf("without mac addr \n");
		return 0;
	}else{
		printf("mac addr Find \n");
	}

	if(read_uuid(readbuf) == 0){
		/* without uuid */
		printf("without uuid\n");
		return 0;
	}else{
		printf("uuid Find \n");
	}

	if(read_bd_info(&readbuf[17]) == 0){
		/* without board info and so on &*/ 
		printf("without boardinfo\n");
		return 0;
	}else{
		printf("board info Find \n");
	}

	memcpy(dev->uuid,readbuf,16);
	dev->deviceType = 0x01;
	memcpy(dev->manufacturer,&readbuf[17],4);
	dev->sortStyle = readbuf[21];
	memcpy(dev->ipaddr,&readbuf[22],4);
	memcpy(dev->netmask,&readbuf[26],4);
	memcpy(dev->gateway,&readbuf[30],4);
	memcpy(dev->seraddr,&readbuf[34],4);
	memcpy(dev->port,&readbuf[38],2);
	memcpy(dev->deviceName,&readbuf[40],80);	

	return 1;
}

static void init_version(void)
{
	int rc;

	bzero(&s3c44b0x,sizeof(s3c44b0x));
	s3c44b0x.frameNums = 12;
	s3c44b0x.hd_version = 0x140F;
	s3c44b0x.sf_version = 0x081C;

	rc = mount("/dev/mtdblock3","/var/yaffs","yaffs",0,0);
	if(rc != 0){
		error_exit(7);
	}

	/* default not any frames need to update */
	deviceUpdate = 0x0;
	memset(update_frames,0,12);
}

static void init_net(OS_BOARD *dev)
{
	int rc;
	char buf[100];

	rc = set_mac_addr(dev->mac);
	if(rc != 0){
		error_exit(rc);
	}	

	rc = set_ip_netmask(dev->ipaddr,dev->netmask);
	if(rc != 0){
		error_exit(rc);
	}

	memset(buf,0,sizeof(buf));
	sprintf(buf,"/sbin/route add default gw %d.%d.%d.%d ",
			dev->gateway[0],dev->gateway[1],dev->gateway[2],dev->gateway[3]);
	if(system(buf) == -1){
		error_exit(8);
	}
}

/*
 *@brief : pthread1
 */
void *keepalive_routine(void *arg)
{
	int  remote_fd = 0,nSendBytes = 0, len = 0;
	int  flags = 0,status = 0,error = 0;
	unsigned int portNum,server_ip = 0;
	struct sockaddr_in remote_addr;
	struct timeval timeout;
	fd_set rset,wset;
	unsigned char msgs[6] = {0x7e,0x00,0x04,0x21,0x89,0x5a};

	struct os_boardinfo dev = *(struct os_boardinfo *)(arg);

	portNum = dev.port[0]*100 + dev.port[1];
	server_ip = dev.seraddr[3] << 24| dev.seraddr[2]<<16| dev.seraddr[1] << 8| dev.seraddr[0];

	for(;;){
		if((remote_fd = socket(AF_INET,SOCK_STREAM,0)) == -1){  
			continue;
		}		 
		remote_addr.sin_family = AF_INET;  
#if 1	
    	remote_addr.sin_port = htons(portNum);  
   		remote_addr.sin_addr.s_addr = server_ip;  
#else 
   	 	remote_addr.sin_port = htons(4700);  
	   	remote_addr.sin_addr.s_addr = inet_addr("192.168.8.219");  
#endif	
	   	bzero(&(remote_addr.sin_zero),8); 	
		/* 将socket句柄重新设置成非阻塞，用于connect连接等待，1秒内没连上，自动断开*/
		flags = fcntl(remote_fd,F_GETFL,0);
		fcntl(remote_fd,F_SETFL,flags|O_NONBLOCK);	
		if(connect(remote_fd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr_in)) == -1){
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;
			FD_ZERO(&wset);
			FD_SET(remote_fd,&wset);
			if(select(remote_fd + 1,NULL,&wset,NULL,&timeout) > 0){
				getsockopt(remote_fd,SOL_SOCKET,SO_ERROR,&error,(socklen_t*)&len);
				if(error != 0){
					close(remote_fd);
				}
			}else{
				close(remote_fd);
			}
		}
		fcntl(remote_fd,F_SETFL,flags & ~O_NONBLOCK); 
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		setsockopt(remote_fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
		nSendBytes = send(remote_fd,msgs,6,0);
		if(nSendBytes == -1){
			sleep(1);
			close(remote_fd);
		}else{
			sleep(1);
			close(remote_fd);
		}
	
		sleep(1);
	}
	
	pthread_detach(pthread_self());
}

static int check_alarm_data(unsigned char *src)
{
	int rc = 0;

	pthread_mutex_lock(&alarm_mutex);

	rc = empty_queue(&fifo_alarm);
	if(rc > 0){
		download_a_task(&fifo_alarm,src);
	}

	pthread_mutex_unlock(&alarm_mutex);

	return rc;
}

/*
 *@brief : pthread2
 */
void *alarm_routine(void *arg)
{
	int  remote_fd = 0,nBytes = 0, len = 0;
	int  flags = 0,status = 0,error = 0;
	unsigned int portNum,server_ip = 0;
	struct sockaddr_in remote_addr;
	struct timeval timeout;
	fd_set rset,wset;
	int rc = 0;
	unsigned char tx_data[1024];
	unsigned char rx_data[10];

	struct os_boardinfo dev = *(struct os_boardinfo *)(arg);

	portNum = dev.port[0]*100 + dev.port[1];
	server_ip = dev.seraddr[3] << 24| dev.seraddr[2]<<16| dev.seraddr[1] << 8| dev.seraddr[0];

	memset(tx_data,0,sizeof(tx_data));

	/* 获取刚才发生的报警数据 */
	pthread_mutex_lock(&alarm_mutex);
	rc = empty_queue(&fifo_alarm);
	if(rc > 0){
		download_a_task(&fifo_alarm,tx_data);
	}
	pthread_mutex_unlock(&alarm_mutex);

	for(;;){

		if((remote_fd = socket(AF_INET,SOCK_STREAM,0)) == -1){  
			continue;
		}		 
		remote_addr.sin_family = AF_INET;  
    	remote_addr.sin_port = htons(portNum);  
   		remote_addr.sin_addr.s_addr = server_ip;  

	   	bzero(&(remote_addr.sin_zero),8); 	
		/* 将socket句柄重新设置成非阻塞，用于connect连接等待，1秒内没连上，自动断开*/
		flags = fcntl(remote_fd,F_GETFL,0);
		fcntl(remote_fd,F_SETFL,flags|O_NONBLOCK);	
		if(connect(remote_fd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr_in)) == -1){
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;
			FD_ZERO(&wset);
			FD_SET(remote_fd,&wset);
			if(select(remote_fd + 1,NULL,&wset,NULL,&timeout) > 0){
				getsockopt(remote_fd,SOL_SOCKET,SO_ERROR,&error,(socklen_t*)&len);
				if(error != 0){
					close(remote_fd);
				}
			}else{
				close(remote_fd);
			}
		}
		fcntl(remote_fd,F_SETFL,flags & ~O_NONBLOCK); 
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		setsockopt(remote_fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
		nBytes = send(remote_fd,tx_data,tx_data[1]<<8|tx_data[2]+2,0);
		if(nBytes == -1){
			close(remote_fd);
			continue;
		}

		timeout.tv_sec = 2;
		timeout.tv_usec = 0;
		setsockopt(remote_fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));
		memset(rx_data,0,sizeof(rx_data));
		nBytes = recv(remote_fd,rx_data,6,0);
		if(nBytes == -1){
			close(remote_fd);
			continue;
		}else{
			if(rx_data[3] == 0xa6){
				memset(tx_data,0,sizeof(tx_data));
			}
		}
	
		close(remote_fd);

		sleep(1);
	}

	pthread_detach(pthread_self());
}

/*
 * @func          : ArrayEmpty
 * @func's own    : (仅供本文件内部调用)
 * @brief         : 检查数组是否为空
 * param[] ...    : \param[1] :数据 | \param[2]:数据来源 :通信串口0(uart0)
 * @created  by   : MingLiang.Lu
 * @created date  : 2014-11-19 
 * @modified by   : MingLiang.Lu
 * @modified date : 2014-11-21 
 */
static int ArrayEmpty(unsigned char *src,unsigned short len)
{
	unsigned int i = 0;
	
	if(src == NULL)
		return 0;

	for(;i < len; i++){
		if(*(src+i) != 0x0)break;	
	}	
	if(i == len)
		return 1;
	else 
		return 0;	
	
}

/*
 * @func          : order_tasks_to_sim3u1xx_board
 * @func's own    : (仅供本文件内部调用)
 * @brief         : 工单任务派发，专门发送函数
 * param[] ...    : \param[1] :数据 | \param[2]:数据来源 :通信串口0(uart0)
 * @created  by   : MingLiang.Lu
 * @created date  : 2014-11-19 
 * @modified by   : MingLiang.Lu
 * @modified date : 2014-11-19 
 */
static int fast_repost_data_to_sim3u146_board(void)
{
	unsigned short TaskFrameDataLength = 0,nBytes = 0;
	unsigned char  TaskPorts[24] = {'\0'};
	unsigned char  i = 0,j = 0;
	unsigned char  debug_buf[10] = {'\0'};

	for(;i < s3c44b0x.frameNums;i++){
		if(uart0.txBuf[i][3] != 0x0)TaskPorts[i] = 1;
	}

	for(;j < 3;j++){//重发机制，3次

		for(i = 0; i < s3c44b0x.frameNums;i++){
			if(TaskPorts[i] == 1){
				TaskFrameDataLength = uart0.txBuf[i][1] << 8| uart0.txBuf[i][2] + 2;
				write(uart0fd,&uart0.txBuf[i][0],TaskFrameDataLength);
				memset(uart0.rxBuf,0,sizeof(uart0.rxBuf));
				usleep(200000);
				nBytes = read(uart0fd,uart0.rxBuf,100);
				if(nBytes > 0){
					if(uart0.rxBuf[3] == 0xa6){
						TaskPorts[i] = 0x0;
						memset(&uart0.txBuf[i][0],0,TX_BUFFER_SIZE);
					}
				}
			}
		}
	}

	if(ArrayEmpty(TaskPorts,24) == 1){
		return 1;
	}else{
		return 0;
	}

} 


/*
 *@function	: write time to mainBoard through Board's RTC module 
 *@datasource:
 *			1: smartphone
 *			2: webmaster
 */
static int write_mainboard_time(unsigned char *time,unsigned char datasource,int sockfd)
{
	int retval = 0;
	struct rtc_time rtc_tm;	
	unsigned char mainBoard_Time_Write_Result[20];

	if(datasource == 1){	/* smartphone */ 
		rtc_tm.tm_year = time[4]*100 + time[5] - 1900; 
		rtc_tm.tm_mon  = time[6] - 1; 
		rtc_tm.tm_mday = time[7]; 
		rtc_tm.tm_hour = time[8]; 
		rtc_tm.tm_min  = time[9]; 
		rtc_tm.tm_sec  = time[10]; 

	}else if(datasource == 3){/*webmaster */
		rtc_tm.tm_year = time[21]*100 + time[22] - 1900; 
		rtc_tm.tm_mon  = time[23] - 1; 
		rtc_tm.tm_mday = time[24]; 
		rtc_tm.tm_hour = time[25]; 
		rtc_tm.tm_min  = time[26]; 
		rtc_tm.tm_sec  = time[27]; 
	
	}

	fprintf(stderr,"\n\nCurrent RTC date/time is :%d-%d-%d,%02d:%02d:%02d.\n", rtc_tm.tm_mday,rtc_tm.tm_mon + 1,time[4]*100 + time[5],  
		rtc_tm.tm_hour,rtc_tm.tm_min,rtc_tm.tm_sec);	

	retval = ioctl(rtcfd, RTC_SET_TIME, &rtc_tm);
	if(retval < 0){
		perror("IOCTL");
		retval = 0x01;
	}

	mainBoard_Time_Write_Result[0] = 0x7e;	
	mainBoard_Time_Write_Result[1] = 0x00;	
	mainBoard_Time_Write_Result[2] = 0x05;	
	mainBoard_Time_Write_Result[3] = 0x15;	
	mainBoard_Time_Write_Result[4] = retval;	
	mainBoard_Time_Write_Result[5] = crc8(mainBoard_Time_Write_Result, 5);	
	mainBoard_Time_Write_Result[6] = 0x5a;	

	if(datasource == 1){	/* replay to smartphone */
		write(uart1fd, mainBoard_Time_Write_Result, mainBoard_Time_Write_Result[1]<<8| mainBoard_Time_Write_Result[2]+2);
	}else if(datasource == 3){/* replay to webmaster */
		if(send(sockfd, mainBoard_Time_Write_Result, mainBoard_Time_Write_Result[1]<<8|mainBoard_Time_Write_Result[2]+2 ,0) == -1){
			usleep(200000);
			close(sockfd);
		}else{
			close(sockfd);
		}
	}

	return 0;
}
/*
 *@function	: read time from mainBoard through Board's RTC module 
 *@datasource:
 *			1: smartphone
 *			2: webmaster
 */
int read_mainboard_time(unsigned char *time_val,unsigned char datasource,int sockfd)
{
	int retval = 0;
	struct rtc_time rtc_tm;
	unsigned char CurrentTime[20];

	retval = ioctl(rtcfd, RTC_RD_TIME, &rtc_tm);
	if(retval < 0){
		perror("RTC IOCTL");
		retval = 0x01;
	}
	
	fprintf(stderr,"\n\nCurrent RTC date/time is :%d-%d-%d,%02d:%02d:%02d.\n", rtc_tm.tm_mday,rtc_tm.tm_mon+1,rtc_tm.tm_year+1900,  
		rtc_tm.tm_hour,rtc_tm.tm_min,rtc_tm.tm_sec);	
	
	CurrentTime[0] = 0x7e;
	CurrentTime[1] = 0x00;
	CurrentTime[2] = 0x0c;
	CurrentTime[3] = 0x16;
	CurrentTime[4] = (rtc_tm.tm_year+1900)/100;
	CurrentTime[5] = (rtc_tm.tm_year+1900)%100;
	CurrentTime[6] = rtc_tm.tm_mon+1;
	CurrentTime[7] = rtc_tm.tm_mday;
	CurrentTime[8] = rtc_tm.tm_hour;
	CurrentTime[9] = rtc_tm.tm_min;
	CurrentTime[10] = rtc_tm.tm_sec;
	CurrentTime[11] = retval;//success or failed 
	CurrentTime[12] = crc8(CurrentTime, 12);
	CurrentTime[13] = 0x5a;

	if(datasource ==  1){/* replay to smartphone */
		write(uart1fd, CurrentTime, CurrentTime[1]<<8|CurrentTime[2]+2);
	}else if(datasource == 3){/* replay to webmaster */
		if(send(sockfd, CurrentTime, CurrentTime[1]<<8|CurrentTime[2]+2, 0) == -1){
			usleep(200000);
			close(sockfd);
		}else{
			close(sockfd);
		}
	}

	return 0;
}

/*
 *
 *	0x10 : led 
 *
 */
static int led_test(unsigned char *src)
{
	unsigned char frameidex = 0;
	
	frameidex = src[4];
	memset(&uart0.txBuf[frameidex-1][0],0,TX_BUFFER_SIZE);
	memcpy(&uart0.txBuf[frameidex-1][0],src,src[2]+2);

	if(!fast_repost_data_to_sim3u146_board()){
		/* maybe mainboard is not exist  */
		return 0;
	}
	
	return 1;
}


/*
 *
 *	0x13: replace_unit_board_cf8051
 *
 */
static int replace_unit_board_cf8051(unsigned char *src,unsigned char dt)
{
	unsigned char frameidex = 0;
	
	switch(dt){
	case 0x01:
		frameidex = src[5];
		memset(&uart0.txBuf[frameidex-1][0],0,TX_BUFFER_SIZE);
		memcpy(&uart0.txBuf[frameidex-1][0],src,src[2]+2);

		if(!fast_repost_data_to_sim3u146_board()){
			/* maybe mainboard is not exist  */
			return 0;
		}
	break;
	case 0x02:
		write(uart1fd,src,src[1]<<8|src[2] + 2);
	break;
	}	

	return 1;
}

/*
 *
 * 0x05
 * dt is short for datatype. 1:mobile 2:uart0
 *
 */
static int rd_devices_version_info(unsigned char *src,unsigned char dt)
{
	unsigned char frameidex = 0;
	unsigned char repost_data[10];
	unsigned char info[30] = {0x7e,0x00,0x0b,0x05,0x01};

	switch(dt){
	case 1:
		if(0xff == src[4]){
			/* read mainboard version info */
			memset(&info[5],0,7);
		
			info[5] = 0x00;//00:mainboard
			info[6] = 0x00;//

			info[7] = s3c44b0x.hd_version >> 8 & 0xff;
			info[8] = s3c44b0x.hd_version & 0xff;
			info[9] = s3c44b0x.sf_version >> 8 & 0xff;
			info[10] = s3c44b0x.sf_version & 0xff;

			info[11] = crc8(info,11);
			info[12] = 0x5a;
	
			write(uart1fd,info,info[1]<<8|info[2] + 2);

		}else{
			memset(repost_data,0,sizeof(repost_data));
			
			memcpy(repost_data,src,6);
			repost_data[2] += 1;
			repost_data[6] = 0x01;
			repost_data[7] = crc8(repost_data,7);
			repost_data[8] = 0x5a;

			frameidex = src[4];
			memset(&uart0.txBuf[frameidex-1][0],0,TX_BUFFER_SIZE);
			memcpy(&uart0.txBuf[frameidex-1][0],repost_data,repost_data[2]+2);

			if(!fast_repost_data_to_sim3u146_board()){
				/* maybe mainboard is not exit  */
				info[5] = src[5];
				info[6] = src[6];

				memset(&info[7],0,4);

				info[11] = crc8(info,11);
				info[12] = 0x5a;

				write(uart1fd,info,info[1]<<8|info[2] + 2);
			}
		}
		break;
	case 2:
		write(uart1fd,src,src[1]<<8|src[2] + 2);
		break;
	default:
		break;
	}

	return 0;
	
}

/*
 * 0x04
 * dt is short for datatype. 1:mobile 2:uart0
 */

static int rd_mainboard_ports_info(unsigned char *src,unsigned char dt)
{
	unsigned char frameidex = 0;
	unsigned short  plen = 0;
	unsigned char data_04_ports_info[400];

	switch(dt){
	case 0x01:
		frameidex = src[4];
		memset(&uart0.txBuf[frameidex-1][0],0,TX_BUFFER_SIZE);
		memcpy(&uart0.txBuf[frameidex-1][0],src,src[2]+2);
		if(!fast_repost_data_to_sim3u146_board()){
	
		}
	break;
	case 0x02:
		memset(data_04_ports_info,0,sizeof(data_04_ports_info));
		plen = src[1]<<8|src[2]+2;
		data_04_ports_info[0] = 0x7e;
		data_04_ports_info[1] = (plen+1-2) >>8 & 0xff;
		data_04_ports_info[2] = (plen+1-2) & 0xff;
		data_04_ports_info[3] = 0x04;
		data_04_ports_info[4] = 0x01;//device type :ODF:01 OCC:02 ...
		memcpy(&data_04_ports_info[5],&uart0.rxBuf[4],plen-4);
		data_04_ports_info[plen-1] = crc8(data_04_ports_info,plen-1);
		data_04_ports_info[plen] = 0x5a;
		write(uart1fd,data_04_ports_info,plen+1);	
	break;
	}

	return 0;
}

/*
 *
 * 0x03
 * dt is short for datatype. 1:mobile 2:uart0
 *
 */
static int rd_mainboard_tray_info(unsigned char *src,unsigned char dt)
{
	unsigned int  nBytes = 0;
	unsigned char frameidex = 0;
	unsigned char i = 0,sended = 0;

	frameidex = src[4];
	for(i = 0;i < 3;i++){
		if(sended){
			memset(uart0.rxBuf,0,30);
			write(uart0fd,poll_sim3u146_cmd,7);
			usleep(180000);
			nBytes = read(uart0fd,uart0.rxBuf,30);
			if(crcCheckout(uart0.rxBuf,30)){
				crcRight[4] = uart0.rxBuf[3];
				crcRight[5] = uart0.rxBuf[4];
				crcRight[6] = frameidex;		
				crcRight[7] = crc8(crcRight,7);		
				write(uart0fd,crcRight,9);
				write(uart1fd,uart0.rxBuf,uart0.rxBuf[1]<<8| uart0.rxBuf[2]+2);
				usleep(180000);	
			
				return 0;
			}
		}else{
			write(uart0fd,src,src[1]<<8|src[2]+2);
			usleep(180000);
			memset(uart0.rxBuf,0,30);
			nBytes = read(uart0fd,uart0.rxBuf,30);
			if(uart0.rxBuf[3] == 0xa6){
				sended = 1;	
				poll_sim3u146_cmd[4] = frameidex;
				poll_sim3u146_cmd[5] = crc8(poll_sim3u146_cmd,5);
				usleep(750000);
			}
		}
	}

	return 0;
}

/*
 *
 *	0x02
 *
 */
static int rd_mainboard_frame_counts(void)
{
	unsigned short nlength = 0x0;
	unsigned char info[40];
	int i;

	memset(info,0,sizeof(info));

	info[0] = 0x7e;
	info[1] = 0x00;
	info[2] = 0x16;
	info[3] = 0x02;
	info[4] = 0x00;//odf device 

	for(i = 0; i < 16;i++){
		if(s3c44b0x.frameactive[i] == 1){
			info[4]++;
			info[5+i] = i+1; 
		}
	}

	nlength = info[1]<<8|info[2];
	info[nlength-1] = s3c44b0x.sortStyle;
	info[nlength] = crc8(info,nlength);
	info[nlength+1] = 0x5a;

	write(uart1fd,info,nlength+2);

	return 0;
}

/*
 *
 *	0x01
 *
 */
static int rd_mainboard_user_info(void) //cmd=0x01:read board info
{
	unsigned char info[130];

	memset(info,0,sizeof(info)); 

	info[0] = 0x7e;
	info[1] = 0x00;
	info[2] = 0x7c;
	info[3] = 0x01;
	info[4] = 0x01;//odf device 

	if(!read_uuid(&info[5])){
		memset(&info[5],0,16);			
	}
	
	if(!read_bd_info(&info[21])){
		memset(&info[21],0,103);
	}

	info[124] = crc8(info,124);
	info[125] = 0x5a;

	write(uart1fd,info,126);

	return 0;
}

/*
 *	read board's MAC
 *
 */
static int read_mainboard_mac(unsigned char *src,unsigned char datatype,int sockfd) //cmd=0x14:write uuid 
{
	FILE *fp = NULL;
	unsigned char mac[13] = {0x7e,0x00,0x0b,0x18}; 

	fp = fopen("/var/yaffs/mac.bin","r+b");
	if(fp == NULL){
		goto withoutmac;
	}

	fseek(fp,0,SEEK_SET);
	memset(&mac[5],0,6);
	fread(&mac[5],sizeof(unsigned char),6,fp);
	mac[4] = 0x00;
	mac[11] = crc8(mac,11);
	mac[12] = 0x5a;

	write(uart1fd,mac,mac[1]<<8|mac[2]+2);

	return 0;

withoutmac:
	mac[4] = 0x01;
	mac[11] = crc8(mac,11);
	mac[12] = 0x5a;
	write(uart1fd,mac,mac[1]<<8|mac[2]+2);
	return 0;
}

/*
 *@function	: write MAC addr to this Board 
 *@cmdkey	: 0x17	 
 *@datasource:
 *			1:smartphone
 *			2:webmaster(Alert !!! webmaster was used to test mode , not for use to customer)
 *
 *
 */
static int write_mainboard_mac(unsigned char *src,unsigned char datatype,int sockfd) //cmd=0x14:write uuid 
{
	FILE *fp = NULL;
	unsigned char tmp_buf[10],i = 0;
	unsigned char mac[7] = {0x7e,0x00,0x05,0x17,0x00,0x00,0x5a}; 

	if(src == NULL)
		return 0;
	
	printf("write mainBoard MAC ...\n");

	fp = fopen("/var/yaffs/mac.bin","w+b");
	if(fp == NULL){
		goto write_MACaddr_failed;
	}

	fwrite(&src[4],sizeof(unsigned char),6,fp); 
	fseek(fp,0,SEEK_SET);
	memset(tmp_buf,0,sizeof(tmp_buf));
	fread(tmp_buf,sizeof(unsigned char),6,fp);
		
	fclose(fp);
	fp = NULL;	
	
	for(i = 0; i < 6;i++){
		if(tmp_buf[i] != *(src+i+4)){
			break;
		}
	}

	if(i != 6){
		goto write_MACaddr_failed;
	}

	mac[4] = 0x0;
	mac[5] = crc8(mac,5);
	mac[6] = 0x5a;
	
	if(1 == datatype){
		write(uart1fd,mac,7);
	}else if (3 == datatype){ 
		if(send(sockfd,mac,7,0) == -1){
			usleep(200000);
			close(sockfd);
		}else{ 
			close(sockfd);
		}
	}

	printf(" Done\n");

	return 0; 

write_MACaddr_failed:
	mac[4] = 0x01; //write failed	
	mac[5] = crc8(mac,5);
	mac[6] = 0x5a;
	if(1 == datatype){
		write(uart1fd,mac,7);
	}else{ 
		if(send(sockfd,mac,7,0) == -1){
			close(sockfd);
		}else{ 
			close(sockfd);
		}
	}
	printf(" Failed!\n");

	return 0;
}
 
/*
 *@function	: write UUID to this Board 
 *@cmdkey	: 0x14	 
 *@datasource:
 *			1:smartphone
 *
 */
static int write_mainboard_uuid(unsigned char *src) //cmd=0x14:write uuid 
{
	FILE *fp = NULL;
	unsigned char tmp_buf[100],i = 0;
	unsigned char uuid[7] = {0x7e,0x00,0x05,0x14,0x00,0x00,0x5a}; 

	if(src == NULL){
		goto write_UUID_failed;
	}

	fp = fopen("/var/yaffs/uuid.bin","w+b");
	if(fp == NULL){
		goto write_UUID_failed;
	}

	fwrite(&src[4],sizeof(unsigned char),16,fp); 
	fseek(fp,0,SEEK_SET);
	memset(tmp_buf,0,sizeof(tmp_buf));
	fread(tmp_buf,sizeof(unsigned char),16,fp);
		
	fclose(fp);
	fp = NULL;	
	
	for(i = 0; i < 16;i++){
		if(tmp_buf[i] != *(src+i+4)){
			break;
		}
	}


	if(i == 16){
		uuid[4] = 0x00; 
	}else{
		goto write_UUID_failed;
	}

	uuid[3] = 0x14;
	uuid[5] = crc8(uuid,5);
	uuid[6] = 0x5a;

	write(uart1fd,uuid,7);
	return 0;

write_UUID_failed:
	uuid[4] = 0x01; 
	uuid[3] = 0x14;
	uuid[5] = crc8(uuid,5);
	uuid[6] = 0x5a;

	write(uart1fd,uuid,7);
	return 0;
}

/*
 * write board's: ip+gateway+netmask+seraddr+port+deviceName 
 *
 */
/*
 *@function	: write BoardIP|GateWay|Netmask|RemoteServerIP|remotePort|DeviceName  
 *@cmdkey	: 0x0c	 
 *@datasource:
 *			1:smartphone
 *
 */
static int write_mainboard_dev_info(unsigned char *src)
{
	FILE *fp = NULL;
	unsigned char tmp_buf[200],i = 0;
	unsigned short len = src[1] << 8 | src[2];
	unsigned char dev_info[23] = {0x7e,0x00,0x15,0x0c};

	if(src == NULL)
		return 0;
	
	fp = fopen("/var/yaffs/boardinfo.bin","w+b");
	if(fp == NULL){
		exit(1);
	}

	fwrite(&src[4],sizeof(unsigned char),len-4,fp);
	memset(tmp_buf,0,sizeof(tmp_buf));

	fseek(fp,0,SEEK_SET);
	fread(tmp_buf,sizeof(unsigned char),len-4,fp);
	
	for(i = 0; i < len - 4;i++){
		if(tmp_buf[i] != *(src+i+4)){
			break;
		}	
	}

	fclose(fp);
	fp  = NULL; 
	
	memcpy(&dev_info[4],tmp_buf,16);
	if(i != len - 4){
		goto write_Devinfo_failed;
	}

	dev_info[20] = 0x00; 
	dev_info[21] = crc8(dev_info,21);
	dev_info[22] = 0x5a;

	write(uart1fd,dev_info,23);
	return 0;

write_Devinfo_failed:
	dev_info[20] = 0x01;
	dev_info[21] = crc8(dev_info,21);
	dev_info[22] = 0x5a;

	write(uart1fd,dev_info,23);
	return 0;
}


/* 网络端服务程序，用来启动哪一个本地服务 */
static void netWork_service_routine(unsigned char *src,int sockfd)
{
	if(0x06 == src[3]){	  /* !xxx -- 软件升级 --  */
		if(src[347] == 0x03){		//update_cf8051
			update_cf8051(3,src,sockfd);	
		}else if(src[347] == 0x02){	//update_sim3u146
			update_sim3u146(3,src,sockfd);	
		}else if(src[347] == 0x01){	//update_s3c44b0x
			update_s3c44b0x(src,sockfd);
		}	
	}else if(0x0c == src[3]){/* !xxx -- 二次采集的覆盖命令 --  */
		second_resource_collect_recover_task(src,sockfd);
	}else if(0x15 == src[3]){/* !xxx -- 网络端写入时间 --  */
		write_mainboard_time(src,3,sockfd);
	}else if(0x16 == src[3]){/* !xxx -- 网络端读取时间 --  */
		read_mainboard_time(src,3,sockfd);
	}else if(0x17 == src[3]){
		write_mainboard_mac(src,3,sockfd);
	}else if(0x20 == src[3]){/* !xxx -- 资源采集 --  */
		module_mainBoard_abortinfo_handle(NULL,1);	
		module_mainBoard_resource_handle(src,sockfd);			
	}else if(0x23 == src[3]){/* !xxx -- 二次采集 --  */
		module_mainBoard_resource_handle(src,sockfd);	
	}else if(0x24 == src[3]){/* !xxx -- 二次采集 --  */
		module_mainBoard_resource_handle(src,sockfd);	 
	}else if(0x0d == src[3]){/* !xxx -- gap -- */	
		if(0x18 == src[4]){	 /* !xxx -- 0x18 -- */
			module_mainBoard_orderOperations_handle(src,3,sockfd);
		}else if(0x19 == src[4]){/* !xxx -- 0x19 -- */
			module_mainBoard_orderOperations_handle(src,3,sockfd);
		}else if(0x30 == src[4]){/* !xxx -- 0x30 -- */
			module_mainBoard_orderOperations_handle(src,3,sockfd);
		}
	}else if(0x0f == src[3]){
		module_mainBoard_ports_appoint_handle(src,3);
		close(sockfd);
	}
}

/*
 *@brief : pthread6
 */
void *net_routine(void *arg)
{
	unsigned char net_temp_data[500];
	int nBytes = 0;
	int client_fd = *((int *)arg);

	memset(net_temp_data,0,sizeof(net_temp_data));
	nBytes = recv(client_fd,net_temp_data,500,0);
	if(nBytes == -1 || nBytes == 0)
	{
		close(client_fd);
	}else
	{
		pthread_mutex_lock(&mobile_mutex);
		if(!crcCheckout(net_temp_data)){
			close(client_fd);
		}else{
		   netWork_service_routine(net_temp_data,client_fd);	
		}
		pthread_mutex_unlock(&mobile_mutex);
	}
	pthread_detach(pthread_self());

}

static void mobilecrcFeedBack(unsigned char *src)
{
	unsigned char  mobile_frame_is_right[25] = {0x7e,0x00,0x17,0x0d,0xa6};

	memset(&mobile_frame_is_right[5],0,17);
	memcpy(&mobile_frame_is_right[5],&src[5],17);
	mobile_frame_is_right[22] = src[4];
	mobile_frame_is_right[23] = crc8(mobile_frame_is_right,23);
	mobile_frame_is_right[24] = 0x5a;

	write(uart1fd,mobile_frame_is_right,25);	
}


/* 手机端服务程序，用来启动哪一个本地的手机端应用程序 */
static void mobile_service_routine(void)
{
	pthread_mutex_lock(&mobile_mutex);
	if(0x01 == mobile_temp_data[3]){	  /* !xxx -- 读取设施配置信息 --  */
		rd_mainboard_user_info();
	}else if(0x02 == mobile_temp_data[3]){/* !xxx -- 读取机框信息 --  */
		rd_mainboard_frame_counts();
	}else if(0x03 == mobile_temp_data[3]){/* !xxx -- 读取盘信息 --  */
		rd_mainboard_tray_info(mobile_temp_data,1);
	}else if(0x04 == mobile_temp_data[3]){/* !xxx -- 读取端口信息 --  */
		rd_mainboard_ports_info(mobile_temp_data,1);
	}else if(0x05 == mobile_temp_data[3]){/* !xxx -- 读取软硬件版本号 --  */
		rd_devices_version_info(mobile_temp_data,1);
	}else if(0x06 == mobile_temp_data[3]){/* !xxx -- 软件升级 -- xxx */
	
	}else if(0x07 == mobile_temp_data[3]){/* !xxx -- 待写入电子标签信息 -- xxx */
	
	}else if(0x09 == mobile_temp_data[3]){/* !xxx -- 读取设施告警信息 -- xxx */
	
	}else if(0x0a == mobile_temp_data[3]){/* !xxx -- 告警确认 -- xxx */
	
	}else if(0x0c == mobile_temp_data[3]){/* !xxx -- 写入设施配置信息 -- xxx */
		write_mainboard_dev_info(mobile_temp_data);
	}else if(0x0d == mobile_temp_data[3]){/* !xxx -- 工单操作 -- xxx */
		if(mobile_temp_data[5] != 0xa3 && mobile_temp_data[5] != 0xa2){
			if(mobile_temp_data[5] != 0x9a){
				mobilecrcFeedBack(mobile_temp_data);	
			}
		}
		module_mainBoard_orderOperations_handle(mobile_temp_data,1,0);
	}else if(0x0e == mobile_temp_data[3]){/* !xxx -- 设备自检 -- xxx */
	
	}else if(0x0f == mobile_temp_data[3]){/* !xxx -- 受控写入电子标签 -- xxx */
		module_mainBoard_ports_appoint_handle(mobile_temp_data,1);
	}else if(0x10 == mobile_temp_data[3]){/* !xxx -- LED指示灯测试 -- xxx */
		led_test(mobile_temp_data);
	}else if(0x11 == mobile_temp_data[3]){/* !xxx -- 系统设备自动配置 -- xxx */
	
	}else if(0x13 == mobile_temp_data[3]){/* !xxx -- 板更换时的数据加载（主控更换、接口板更换、单元板更换） -- xxx */
		replace_unit_board_cf8051(mobile_temp_data,1);
	}else if(0x14 == mobile_temp_data[3]){/* !xxx -- 写入设备UUID -- xxx */
		write_mainboard_uuid(mobile_temp_data);
	}else if(0x15 == mobile_temp_data[3]){/* !xxx -- 写入设备时间 -- xxx */
		write_mainboard_time(mobile_temp_data,1,0);
	}else if(0x16 == mobile_temp_data[3]){/* !xxx -- 读取设备时间 -- xxx */
		read_mainboard_time(mobile_temp_data,1,0);
	}else if(0x17 == mobile_temp_data[3]){/* !xxx -- 写入MAC Addr -- xxx */
		write_mainboard_mac(mobile_temp_data,1,0);
	}else if(0x18 == mobile_temp_data[3]){/* !xxx -- 读取MAC Addr -- xxx */
		read_mainboard_mac(mobile_temp_data,1,0);
	}else if(0xa6 == mobile_temp_data[3]){
		if(0x0c == mobile_temp_data[4]){
			system("/sbin/reboot");
		}
	}

	memset(mobile_temp_data,0,sizeof(mobile_temp_data));

	pthread_mutex_unlock(&mobile_mutex);
}

/*
 *@brief : pthread3
 */
void *mobile_routine(void *arg)
{
	int nBytes = 0;

	for(;;){

		memset(mobile_temp_data,0,sizeof(mobile_temp_data));
		nBytes = read(uart1fd,mobile_temp_data,200); 
		if(nBytes >= 5 && crcCheckout(mobile_temp_data)){
			if(mobile_temp_data[4] != 0xa6) {
				mobile_service_routine();
			}
		}
		usleep(400000);
	}
	
	pthread_detach(pthread_self());
}

static unsigned char scan_sim3u1xx_boards(void)
{
	static unsigned char boardnum = 1;
	unsigned char c_frame = 0,i = 0;

	if(deviceUpdate == 0x1){
		/* maybe some frames is updating now */
		for(i = 0; i < 12; i++){
			if((update_frames[i] == 0x1) && (update_status[i] == 0xEE)){
				boardnum = i + 1;
				break;
			}
		}

		if(boardnum == 12)
			deviceUpdate = 0x0;
	}
	poll_sim3u146_cmd[4] = boardnum;
	poll_sim3u146_cmd[5] = crc8(poll_sim3u146_cmd,5);
	write(uart0fd,poll_sim3u146_cmd,7);	
	c_frame = boardnum;
	boardnum += 1;
	if(boardnum > 16)boardnum = 1;
	
	return c_frame;
}


/* 接口送上了的信息处理 */
static void sim3u1xx_info_handle(void)
{
	unsigned  char src_cmd = 0;
	
	src_cmd = uart0.rxBuf[3];

	switch(src_cmd){
		case 0x04:
			rd_mainboard_ports_info(uart0.rxBuf,2);
		break;	
		case 0x05:
			rd_devices_version_info(uart0.rxBuf,2);
			break;
		case 0x06:
			if(uart0.rxBuf[5] == 0x03){
				update_cf8051(2,uart0.rxBuf,0);
			}else if(uart0.rxBuf[5] == 0x02){
				update_sim3u146(2,uart0.rxBuf,0);
			}
		break;		
		case 0x09:
			module_mainBoard_abortinfo_handle(uart0.rxBuf,0);
			break;
		case 0x0d:
			module_mainBoard_orderOperations_handle(uart0.rxBuf,2,0);
			break;
		case 0x0f:
			module_mainBoard_ports_appoint_handle(uart0.rxBuf,2);
			break;
		case 0x13:
			replace_unit_board_cf8051(uart0.rxBuf,2);
			break;
		default:
			break;
	}
}


static void crc8_sim3u1xxx_data(unsigned char c_frame)
{
	if(crcCheckout(uart0.rxBuf)){
	//且CRC对的
		if(uart0.rxBuf[3] == 0x20){
		//do nothing
		}else if(uart0.rxBuf[3] == 0xa6 || uart0.rxBuf[3] == 0xf6){
			memset(&uart0.txBuf[uart0.rxBuf[4]-1][0],0,sizeof(uart0.txBuf[uart0.rxBuf[4]-1]));	
		}else{
			crcRight[4] = uart0.rxBuf[3];
			crcRight[5] = uart0.rxBuf[4];
			crcRight[6] = c_frame;		
			crcRight[7] = crc8(crcRight,7);		
			write(uart0fd,crcRight,9);
			usleep(180000);
			sim3u1xx_info_handle();
		 }
	}else{
	//但CRC不对
		crcWrong[4] = uart0.rxBuf[3];
		crcWrong[5] = uart0.rxBuf[4];
		crcWrong[6] = c_frame;
		crcWrong[7] = crc8(crcWrong,7);		
		write(uart0fd,crcWrong,9);			
		usleep(180000);
	}
}
/*
 *@brief : pthread4
 */
void *poll_sim3u146_routine(void *arg)
{
	int nBytes = 0;
	unsigned char board = 0;

	for(;;){
		pthread_mutex_lock(&mobile_mutex);
		board = scan_sim3u1xx_boards();
		usleep(300000);
		memset(uart0.rxBuf,0,400);
		nBytes = read(uart0fd,uart0.rxBuf,400);
		if(nBytes >= 6){
			crc8_sim3u1xxx_data(board);
		}
		pthread_mutex_unlock(&mobile_mutex);
		usleep(30000);
	}

	pthread_detach(pthread_self());
}


/*
 *@brief : pthread5
 */
void *server_routine(void *arg)
{
	unsigned short int port = DEFAULT_PORT;
	//循环接受client请求
	int new_sock,res,i,recv_size;
	struct sockaddr_in client_addr;
	socklen_t client_addr_len;
	int yes = 1;
	struct sockaddr_in bind_addr;
	pthread_t pthid;
	int maxfd;
	//创建socket
	int sock;

	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		exit(EXIT_FAILURE);
	}
	//in case of 'address already in use' error message
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))){
		exit(EXIT_FAILURE);
	}
	//创建要bind的socket address
	memset(&bind_addr, 0, sizeof(bind_addr));
	bind_addr.sin_family = AF_INET;
	bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //设置接受任意地址
	bind_addr.sin_port = htons(port);               //将host byte order转换为network byte order
	//bind sock到创建的socket address上
	if(bind(sock,(struct sockaddr *)&bind_addr,sizeof(bind_addr)) == -1){
		exit(EXIT_FAILURE);
	}
	//listen
	if(listen(sock, 10) == -1){
		exit(EXIT_FAILURE);
	}

	maxfd = sock;
	for(;;){
		//当前是server的socket，不进行读写而是accept新连接
		client_addr_len = sizeof(client_addr);
		new_sock = accept(sock, (struct sockaddr *)&client_addr,&client_addr_len);
		if (new_sock == -1) {
			continue;
		}else{
			if(pthread_create(&pthid,NULL,net_routine,(void *)&new_sock) == -1){
					//do nothing 
				close(new_sock);
			}
		}
	}

	return 0;

	pthread_detach(pthread_self());
}


static void detecet_sim3u1xx_boards_numbers(void)
{
	unsigned char sim3u1xx_board = 1, i = 0;	
	unsigned char maxFrameIdex = 16;

	Maxframenum = 0;

	for(;i < maxFrameIdex;i++)
	{
		poll_sim3u146_cmd[4] = sim3u1xx_board;
		poll_sim3u146_cmd[5] = crc8(poll_sim3u146_cmd,5);		
		write(uart0fd,poll_sim3u146_cmd,7);
		usleep(300000);
		if(read(uart0fd,uart0.rxBuf,300)){
			if(crcCheckout(uart0.rxBuf)){
				s3c44b0x.frameactive[sim3u1xx_board-1] = 1;
				if(sim3u1xx_board > Maxframenum)
						Maxframenum = sim3u1xx_board;
			}else{
				s3c44b0x.frameactive[sim3u1xx_board-1] = 0;
			}
		}else{
			s3c44b0x.frameactive[sim3u1xx_board-1] = 0;
		}
		if(sim3u1xx_board++ > maxFrameIdex)sim3u1xx_board = 1;
	}

	s3c44b0x.frameNums = Maxframenum;
	s3c44b0x.totalactiveDevices = 0;
	for(i = 0; i < s3c44b0x.frameNums; i++){
		if(s3c44b0x.frameactive[i] == 1){
			s3c44b0x.totalactiveDevices++;
		}
	}
	
}

int main(int argc,char *argv[])
{
	pthread_t thid[10];

	volatile int rc = 0;
	volatile int configed = 0;
	
	init_version();
	open_devices();

	configed = read_dev_info(&s3c44b0x);
	if(configed == 0)
	{
		printf("\n");
		printf("###############################Alert##################################\n");
		printf("Board not Configed !!! Just start running Mobile Config Routine ...\n");
		printf("Current Time 2015-08-28 11:07\n");
		printf("######################################################################\n");
		rc = pthread_create(&thid[0],NULL,mobile_routine,NULL);
		if(rc == -1){
			error_exit(1);
		}else{
			printf("Mobile Config Routine is ready! \n");
		}
		printf("\n");
	}else 
	{
		printf("\n");
		printf("###############################Alert##################################\n");
		printf("Board Configed !!! Find uuid|MAC|ip|gateway|serverip.Config ...Done\n");	
		printf("Current Time 2015-08-28 11:07\n");
		printf("######################################################################\n");
		printf("\n");

		/* 配置网络参数: MAC addr , Ip, Gateway ,Netmask etc */
		init_net(&s3c44b0x);

		/* 把告警信息清掉，以后可能从数据库中加载告警信息 */
		reset_odf_alarm_entires();
		signal(SIGPIPE,SIG_IGN);

		rc = pthread_create(&thid[0],NULL,keepalive_routine,(void *)&s3c44b0x);
		if(rc == -1){
			error_exit(1);
		}
		
		rc = pthread_create(&thid[2],NULL,server_routine,NULL);
		if(rc == -1){
			error_exit(3);
		}

#if 0		
		rc = pthread_create(&thid[3],NULL,gap_recv_thid,NULL);
		if(rc == -1){
			error_exit(3);
		}
#endif 	
		
		rc = pthread_create(&thid[4],NULL,mobile_routine,NULL);
		if(rc == -1){
			error_exit(4);
		}
	
		detecet_sim3u1xx_boards_numbers();

		rc = pthread_create(&thid[5],NULL,poll_sim3u146_routine,NULL);
		if(rc == -1){
			error_exit(5);
		}	

	}

	/* endless forever */
	while(1){
	
	}

	return 0;
}	


